package com.zjl.学习.第05章_作业控制.C_作业重启;

import com.zjl.springbatch.util.OutColour;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.nio.charset.Charset;

/**
 * 作业重启，表示允许作业步骤重新执行，默认情况下，只允许异常或终止状态的步骤重启，
 * 但有时存在特殊场景，要求需要其他状态步骤重启，为应付各种复杂的情形，Spring Batch 提供3种重启控制操作。
 *
 * 1.禁止重启
 *  这种适用一次性执行场景，如果执行失败，就不允许再次执行。可以使用作业的禁止重启逻辑
 * 2.限制重启次数
 * 适用于重启次数有限的场景，比如下载/读取操作，可能因为网络原因导致下载/读取失败，运行重试几次，但是不能无限重试。这时可以对步骤执行进行重启次数限制。
 * 3.无限重启
 * Spring Batch 限制同job名跟同标识参数作业只能成功执行一次，这是Spring Batch 定理，无法改变的。
 * 但是，对于步骤不一定适用，可以通过步骤的allowStartIfComplete(true) 实现步骤的无限重启。
 *
 */
@SpringBootApplication
@EnableBatchProcessing//开启spring batch
public class C_作业重启 {
    public static void main(String[] args) {
        System.setProperty("spring.profiles.active","01");
        SpringApplication.run(C_作业重启.class, args);
        System.out.println("***********启动完毕**当前编码:" + Charset.defaultCharset().name() + "****************");

    }

    @Autowired//@EnableBatchProcessing 这个注解帮你从 spring batch 的配置文件中加载了
    private JobLauncher jobLauncher;//Job 启动器
    @Autowired//Job 构造工厂
    private JobBuilderFactory jobBuilderFactory;
    @Autowired//构建 Step
    private StepBuilderFactory stepBuilderFactory;
    @Bean//任务 Tasklet 这是最简单的    还有Chunk块处理
    public Tasklet tasklet05A(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                chunkContext.getStepContext().getStepExecution().setTerminateOnly();//设置 此操作状态为   STOPPED  //表示已完成的加工 中断状态停止

                OutColour.out.printlnRed("****************A*******************");
                return RepeatStatus.FINISHED;//已完成
            }
        };
    }
    @Bean
    public Tasklet tasklet05B(){
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                OutColour.out.printlnRed("****************B*******************");
                return RepeatStatus.FINISHED;//已完成
            }
        };
    }

    @Bean
    public Step step05A() throws Exception {
        return stepBuilderFactory.get("step05A")
                .tasklet(tasklet05A())
//                .startLimit(2)//最多重启次数  // Maximum start limit exceeded for step: step05AStartMax: 2

                //给所有步骤加上 .allowStartIfComplete(true) 就间接实现无限重启
//                .allowStartIfComplete(true)//允许此步骤可重复执行//表示无论如何，都会执行此步骤
                .build();
    }
    @Bean
    public Step step05B() throws Exception {
        return stepBuilderFactory.get("step05B").tasklet(tasklet05B()).build();
    }
    @Bean
    public Job job005zycq() throws Exception {
        return jobBuilderFactory.get("job005作业的重启3")
//                .preventRestart()//禁止重启
                .start(step05A())
                .next(step05B())
                .build();

    }
}
